﻿using System.Reflection.Emit;
using System;
using System.Collections.Generic;
using System.Reflection;
using ProxyViewModel.Commands;
namespace ProxyViewModel.Emitors {
	public abstract class EmitorBase {
		private readonly TypeBuilder _typeBuilder;
		private readonly Type _operatable;
		private readonly IDictionary<string, object> _parameters;
		private EmitorBase _nextEmitor;

		protected IDictionary<string, object> CurrentParameters {
			get { return _parameters; }
		}

		public Type Operatable {
			get { return _operatable; }
		}

		protected TypeBuilder TypeBuilder {
			get { return _typeBuilder; }
		}

		public EmitorBase(TypeBuilder typeBuilder, Type operatable, IDictionary<string, object> parameters) {
			_typeBuilder = typeBuilder;
			_operatable = operatable;
			_parameters = parameters;
		}

		protected virtual void OnConstruction(ILGenerator il) { }

		protected T GetParameter<T>(string parameterName) {
			if (_parameters.ContainsKey(parameterName)) {
				return (T)_parameters[parameterName];
			}
			else {
				return default(T);
			}
		}

		public void Emit() {
			EmitContent();
		}

		public void CallMethodOnConstruction(MethodInfo info) {
			if (!_parameters.ContainsKey(Parameters.MethodsToCallOnConstructionKey)) {
				_parameters[Parameters.MethodsToCallOnConstructionKey] = new List<MethodInfo>();
			}
			((List<MethodInfo>)_parameters[Parameters.MethodsToCallOnConstructionKey]).Add(info);
		}

		protected abstract void EmitContent();
	}
}
